﻿// Decompiled with JetBrains decompiler
// Type: UnityEngine.Texture3D
// Assembly: UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E6AE6B5A-2752-4B07-9528-C8B77C62CE79
// Assembly location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll
// XML documentation location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.xml

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine.Bindings;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Internal;
using UnityEngine.Scripting;

#nullable disable
namespace UnityEngine
{
  /// <summary>
  ///   <para>Class for handling 3D Textures, Use this to create.</para>
  /// </summary>
  [NativeHeader("Runtime/Graphics/Texture3D.h")]
  [ExcludeFromPreset]
  public sealed class Texture3D : Texture
  {
    /// <summary>
    ///   <para>The depth of the texture (Read Only).</para>
    /// </summary>
    public extern int depth { [NativeName("GetTextureLayerCount"), MethodImpl(MethodImplOptions.InternalCall)] get; }

    /// <summary>
    ///   <para>The format of the pixel data in the texture (Read Only).</para>
    /// </summary>
    public extern TextureFormat format { [NativeName("GetTextureFormat"), MethodImpl(MethodImplOptions.InternalCall)] get; }

    public override extern bool isReadable { [MethodImpl(MethodImplOptions.InternalCall)] get; }

    [NativeName("SetPixel")]
    private void SetPixelImpl(int mip, int x, int y, int z, Color color)
    {
      this.SetPixelImpl_Injected(mip, x, y, z, ref color);
    }

    [NativeName("GetPixel")]
    private Color GetPixelImpl(int mip, int x, int y, int z)
    {
      Color ret;
      this.GetPixelImpl_Injected(mip, x, y, z, out ret);
      return ret;
    }

    [NativeName("GetPixelBilinear")]
    private Color GetPixelBilinearImpl(int mip, float u, float v, float w)
    {
      Color ret;
      this.GetPixelBilinearImpl_Injected(mip, u, v, w, out ret);
      return ret;
    }

    [FreeFunction("Texture3DScripting::Create")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern bool Internal_CreateImpl(
      [Writable] Texture3D mono,
      int w,
      int h,
      int d,
      int mipCount,
      GraphicsFormat format,
      TextureColorSpace colorSpace,
      TextureCreationFlags flags,
      IntPtr nativeTex);

    private static void Internal_Create(
      [Writable] Texture3D mono,
      int w,
      int h,
      int d,
      int mipCount,
      GraphicsFormat format,
      TextureColorSpace colorSpace,
      TextureCreationFlags flags,
      IntPtr nativeTex)
    {
      if (!Texture3D.Internal_CreateImpl(mono, w, h, d, mipCount, format, colorSpace, flags, nativeTex))
        throw new UnityException("Failed to create texture because of invalid parameters.");
    }

    /// <summary>
    ///   <para>Updates Unity texture to use different native texture object.</para>
    /// </summary>
    /// <param name="nativeTex">Native 3D texture object.</param>
    [FreeFunction("Texture3DScripting::UpdateExternalTexture", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void UpdateExternalTexture(IntPtr nativeTex);

    [FreeFunction(Name = "Texture3DScripting::Apply", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void ApplyImpl(bool updateMipmaps, bool makeNoLongerReadable);

    /// <summary>
    ///   <para>Gets the pixel color data for a mipmap level as Color structs.</para>
    /// </summary>
    /// <param name="miplevel">The mipmap level to get. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <returns>
    ///   <para>An array that contains the pixel colors.</para>
    /// </returns>
    [FreeFunction(Name = "Texture3DScripting::GetPixels", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern Color[] GetPixels(int miplevel);

    /// <summary>
    ///   <para>Gets the pixel color data for a mipmap level as Color structs.</para>
    /// </summary>
    /// <param name="miplevel">The mipmap level to get. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <returns>
    ///   <para>An array that contains the pixel colors.</para>
    /// </returns>
    public Color[] GetPixels() => this.GetPixels(0);

    /// <summary>
    ///   <para>Gets the pixel color data for a mipmap level as Color32 structs.</para>
    /// </summary>
    /// <param name="miplevel">The mipmap level to get. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <returns>
    ///   <para>An array that contains the pixel colors.</para>
    /// </returns>
    [FreeFunction(Name = "Texture3DScripting::GetPixels32", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern Color32[] GetPixels32(int miplevel);

    /// <summary>
    ///   <para>Gets the pixel color data for a mipmap level as Color32 structs.</para>
    /// </summary>
    /// <param name="miplevel">The mipmap level to get. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <returns>
    ///   <para>An array that contains the pixel colors.</para>
    /// </returns>
    public Color32[] GetPixels32() => this.GetPixels32(0);

    /// <summary>
    ///   <para>Sets the pixel colors of an entire mipmap level.</para>
    /// </summary>
    /// <param name="colors">The array of pixel colours to use. This is a 3D texture flattened to a 1D array.</param>
    /// <param name="miplevel">The mipmap level to write colors to. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    [FreeFunction(Name = "Texture3DScripting::SetPixels", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void SetPixels([Unmarshalled] Color[] colors, int miplevel);

    /// <summary>
    ///   <para>Sets the pixel colors of an entire mipmap level.</para>
    /// </summary>
    /// <param name="colors">The array of pixel colours to use. This is a 3D texture flattened to a 1D array.</param>
    /// <param name="miplevel">The mipmap level to write colors to. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    public void SetPixels(Color[] colors) => this.SetPixels(colors, 0);

    /// <summary>
    ///   <para>Sets the pixel colors of an entire mipmap level.</para>
    /// </summary>
    /// <param name="colors">The array of pixel colours to use. This is a 3D texture flattened to a 1D array.</param>
    /// <param name="miplevel">The mipmap level to write colors to. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    [FreeFunction(Name = "Texture3DScripting::SetPixels32", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void SetPixels32([Unmarshalled] Color32[] colors, int miplevel);

    /// <summary>
    ///   <para>Sets the pixel colors of an entire mipmap level.</para>
    /// </summary>
    /// <param name="colors">The array of pixel colours to use. This is a 3D texture flattened to a 1D array.</param>
    /// <param name="miplevel">The mipmap level to write colors to. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    public void SetPixels32(Color32[] colors) => this.SetPixels32(colors, 0);

    [FreeFunction(Name = "Texture3DScripting::SetPixelDataArray", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern bool SetPixelDataImplArray(
      Array data,
      int mipLevel,
      int elementSize,
      int dataArraySize,
      int sourceDataStartIndex = 0);

    [FreeFunction(Name = "Texture3DScripting::SetPixelData", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern bool SetPixelDataImpl(
      IntPtr data,
      int mipLevel,
      int elementSize,
      int dataArraySize,
      int sourceDataStartIndex = 0);

    private AtomicSafetyHandle GetSafetyHandleForSlice(int mipLevel)
    {
      AtomicSafetyHandle ret;
      this.GetSafetyHandleForSlice_Injected(mipLevel, out ret);
      return ret;
    }

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern IntPtr GetImageDataPointer();

    [ExcludeFromDocs]
    public Texture3D(
      int width,
      int height,
      int depth,
      DefaultFormat format,
      TextureCreationFlags flags)
      : this(width, height, depth, SystemInfo.GetGraphicsFormat(format), flags)
    {
    }

    [RequiredByNativeCode]
    [ExcludeFromDocs]
    public Texture3D(
      int width,
      int height,
      int depth,
      GraphicsFormat format,
      TextureCreationFlags flags)
      : this(width, height, depth, format, flags, Texture.GenerateAllMips)
    {
    }

    [ExcludeFromDocs]
    public Texture3D(
      int width,
      int height,
      int depth,
      GraphicsFormat format,
      TextureCreationFlags flags,
      [DefaultValue("-1")] int mipCount)
    {
      if (!this.ValidateFormat(format, FormatUsage.Sample))
        return;
      Texture3D.ValidateIsNotCrunched(flags);
      Texture3D.Internal_Create(this, width, height, depth, mipCount, format, this.GetTextureColorSpace(format), flags, IntPtr.Zero);
    }

    [ExcludeFromDocs]
    public Texture3D(int width, int height, int depth, TextureFormat textureFormat, int mipCount)
    {
      if (!this.ValidateFormat(textureFormat))
        return;
      GraphicsFormat graphicsFormat = GraphicsFormatUtility.GetGraphicsFormat(textureFormat, false);
      TextureCreationFlags flags = mipCount != 1 ? TextureCreationFlags.MipChain : TextureCreationFlags.None;
      if (GraphicsFormatUtility.IsCrunchFormat(textureFormat))
        flags |= TextureCreationFlags.Crunch;
      Texture3D.ValidateIsNotCrunched(flags);
      Texture3D.Internal_Create(this, width, height, depth, mipCount, graphicsFormat, this.GetTextureColorSpace(true), flags, IntPtr.Zero);
    }

    /// <summary>
    ///   <para>Create a new empty 3D Texture.</para>
    /// </summary>
    /// <param name="width">Width of texture in pixels.</param>
    /// <param name="height">Height of texture in pixels.</param>
    /// <param name="depth">Depth of texture in pixels.</param>
    /// <param name="textureFormat">Texture data format.</param>
    /// <param name="mipChain">Determines whether the texture has mipmaps or not. A value of 1 (true) means the texture does have mipmaps, and a value of 0 (false) means the texture doesn't have mipmaps.</param>
    /// <param name="nativeTex">External native texture pointer to use. Defaults to generating its own internal native texture.</param>
    /// <param name="mipCount">Amount of mipmaps to allocate for the texture.</param>
    public Texture3D(
      int width,
      int height,
      int depth,
      TextureFormat textureFormat,
      int mipCount,
      [DefaultValue("IntPtr.Zero")] IntPtr nativeTex)
    {
      if (!this.ValidateFormat(textureFormat))
        return;
      GraphicsFormat graphicsFormat = GraphicsFormatUtility.GetGraphicsFormat(textureFormat, false);
      TextureCreationFlags flags = mipCount != 1 ? TextureCreationFlags.MipChain : TextureCreationFlags.None;
      if (GraphicsFormatUtility.IsCrunchFormat(textureFormat))
        flags |= TextureCreationFlags.Crunch;
      Texture3D.ValidateIsNotCrunched(flags);
      Texture3D.Internal_Create(this, width, height, depth, mipCount, graphicsFormat, this.GetTextureColorSpace(true), flags, nativeTex);
    }

    /// <summary>
    ///   <para>Create a new empty 3D Texture.</para>
    /// </summary>
    /// <param name="width">Width of texture in pixels.</param>
    /// <param name="height">Height of texture in pixels.</param>
    /// <param name="depth">Depth of texture in pixels.</param>
    /// <param name="textureFormat">Texture data format.</param>
    /// <param name="mipChain">Determines whether the texture has mipmaps or not. A value of 1 (true) means the texture does have mipmaps, and a value of 0 (false) means the texture doesn't have mipmaps.</param>
    /// <param name="nativeTex">External native texture pointer to use. Defaults to generating its own internal native texture.</param>
    /// <param name="mipCount">Amount of mipmaps to allocate for the texture.</param>
    [ExcludeFromDocs]
    public Texture3D(
      int width,
      int height,
      int depth,
      TextureFormat textureFormat,
      bool mipChain)
      : this(width, height, depth, textureFormat, mipChain ? -1 : 1)
    {
    }

    /// <summary>
    ///   <para>Create a new empty 3D Texture.</para>
    /// </summary>
    /// <param name="width">Width of texture in pixels.</param>
    /// <param name="height">Height of texture in pixels.</param>
    /// <param name="depth">Depth of texture in pixels.</param>
    /// <param name="textureFormat">Texture data format.</param>
    /// <param name="mipChain">Determines whether the texture has mipmaps or not. A value of 1 (true) means the texture does have mipmaps, and a value of 0 (false) means the texture doesn't have mipmaps.</param>
    /// <param name="nativeTex">External native texture pointer to use. Defaults to generating its own internal native texture.</param>
    /// <param name="mipCount">Amount of mipmaps to allocate for the texture.</param>
    public Texture3D(
      int width,
      int height,
      int depth,
      TextureFormat textureFormat,
      bool mipChain,
      [DefaultValue("IntPtr.Zero")] IntPtr nativeTex)
      : this(width, height, depth, textureFormat, mipChain ? -1 : 1, nativeTex)
    {
    }

    /// <summary>
    ///   <para>Creates Unity Texture out of externally created native texture object.</para>
    /// </summary>
    /// <param name="nativeTex">Native 3D texture object.</param>
    /// <param name="width">Width of texture in pixels.</param>
    /// <param name="height">Height of texture in pixels.</param>
    /// <param name="depth">Depth of texture in pixels</param>
    /// <param name="format">Format of underlying texture object.</param>
    /// <param name="mipmap">Does the texture have mipmaps?</param>
    /// <param name="mipChain"></param>
    public static Texture3D CreateExternalTexture(
      int width,
      int height,
      int depth,
      TextureFormat format,
      bool mipChain,
      IntPtr nativeTex)
    {
      if (nativeTex == IntPtr.Zero)
        throw new ArgumentException("nativeTex may not be zero");
      return new Texture3D(width, height, depth, format, mipChain ? -1 : 1, nativeTex);
    }

    /// <summary>
    ///   <para>Copies changes you've made in a CPU texture to the GPU.</para>
    /// </summary>
    /// <param name="updateMipmaps">When the value is true, Unity recalculates mipmap levels, using mipmap level 0 as the source. The default value is true.</param>
    /// <param name="makeNoLongerReadable">When the value is true, Unity deletes the texture in CPU memory after it uploads it to the GPU, and sets Texture.isReadable|isReadable to false. The default value is false.</param>
    public void Apply([DefaultValue("true")] bool updateMipmaps, [DefaultValue("false")] bool makeNoLongerReadable)
    {
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      this.ApplyImpl(updateMipmaps, makeNoLongerReadable);
    }

    [ExcludeFromDocs]
    public void Apply(bool updateMipmaps) => this.Apply(updateMipmaps, false);

    [ExcludeFromDocs]
    public void Apply() => this.Apply(true, false);

    /// <summary>
    ///   <para>Sets the pixel color at coordinates (x, y, z).</para>
    /// </summary>
    /// <param name="x">The x coordinate of the pixel to set. The range is 0 through the (texture width - 1).</param>
    /// <param name="y">The y coordinate of the pixel to set. The range is 0 through the (texture height - 1).</param>
    /// <param name="z">The z coordinate of the pixel to set. The range is 0 through the (texture depth - 1).</param>
    /// <param name="color">The color to set.</param>
    /// <param name="mipLevel">The mipmap level to write to. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    [ExcludeFromDocs]
    public void SetPixel(int x, int y, int z, Color color)
    {
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      this.SetPixelImpl(0, x, y, z, color);
    }

    /// <summary>
    ///   <para>Sets the pixel color at coordinates (x, y, z).</para>
    /// </summary>
    /// <param name="x">The x coordinate of the pixel to set. The range is 0 through the (texture width - 1).</param>
    /// <param name="y">The y coordinate of the pixel to set. The range is 0 through the (texture height - 1).</param>
    /// <param name="z">The z coordinate of the pixel to set. The range is 0 through the (texture depth - 1).</param>
    /// <param name="color">The color to set.</param>
    /// <param name="mipLevel">The mipmap level to write to. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    public void SetPixel(int x, int y, int z, Color color, [DefaultValue("0")] int mipLevel)
    {
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      this.SetPixelImpl(mipLevel, x, y, z, color);
    }

    /// <summary>
    ///   <para>Gets the pixel color at coordinates (x, y, z).</para>
    /// </summary>
    /// <param name="x">The x coordinate of the pixel to get. The range is 0 through the (texture width - 1).</param>
    /// <param name="y">The y coordinate of the pixel to get. The range is 0 through the (texture height - 1).</param>
    /// <param name="z">The z coordinate of the pixel to get. The range is 0 through the (texture depth - 1).</param>
    /// <param name="mipLevel">The mipmap level to sample. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <returns>
    ///   <para>The pixel color.</para>
    /// </returns>
    [ExcludeFromDocs]
    public Color GetPixel(int x, int y, int z)
    {
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      return this.GetPixelImpl(0, x, y, z);
    }

    /// <summary>
    ///   <para>Gets the pixel color at coordinates (x, y, z).</para>
    /// </summary>
    /// <param name="x">The x coordinate of the pixel to get. The range is 0 through the (texture width - 1).</param>
    /// <param name="y">The y coordinate of the pixel to get. The range is 0 through the (texture height - 1).</param>
    /// <param name="z">The z coordinate of the pixel to get. The range is 0 through the (texture depth - 1).</param>
    /// <param name="mipLevel">The mipmap level to sample. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <returns>
    ///   <para>The pixel color.</para>
    /// </returns>
    public Color GetPixel(int x, int y, int z, [DefaultValue("0")] int mipLevel)
    {
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      return this.GetPixelImpl(mipLevel, x, y, z);
    }

    /// <summary>
    ///   <para>Gets the filtered pixel color at the normalized coordinates (u, v, w).</para>
    /// </summary>
    /// <param name="u">The u coordinate of the pixel to get.</param>
    /// <param name="v">The v coordinate of the pixel to get.</param>
    /// <param name="w">The w coordinate of the pixel to get.</param>
    /// <param name="mipLevel">The mipmap level to read from. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <returns>
    ///   <para>The pixel color.</para>
    /// </returns>
    [ExcludeFromDocs]
    public Color GetPixelBilinear(float u, float v, float w)
    {
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      return this.GetPixelBilinearImpl(0, u, v, w);
    }

    /// <summary>
    ///   <para>Gets the filtered pixel color at the normalized coordinates (u, v, w).</para>
    /// </summary>
    /// <param name="u">The u coordinate of the pixel to get.</param>
    /// <param name="v">The v coordinate of the pixel to get.</param>
    /// <param name="w">The w coordinate of the pixel to get.</param>
    /// <param name="mipLevel">The mipmap level to read from. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <returns>
    ///   <para>The pixel color.</para>
    /// </returns>
    public Color GetPixelBilinear(float u, float v, float w, [DefaultValue("0")] int mipLevel)
    {
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      return this.GetPixelBilinearImpl(mipLevel, u, v, w);
    }

    public void SetPixelData<T>(T[] data, int mipLevel, [DefaultValue("0")] int sourceDataStartIndex = 0)
    {
      if (sourceDataStartIndex < 0)
        throw new UnityException("SetPixelData: sourceDataStartIndex cannot be less than 0.");
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      if (data == null || data.Length == 0)
        throw new UnityException("No texture data provided to SetPixelData.");
      this.SetPixelDataImplArray((Array) data, mipLevel, Marshal.SizeOf((object) data[0]), data.Length, sourceDataStartIndex);
    }

    public unsafe void SetPixelData<T>(NativeArray<T> data, int mipLevel, [DefaultValue("0")] int sourceDataStartIndex = 0) where T : struct
    {
      if (sourceDataStartIndex < 0)
        throw new UnityException("SetPixelData: sourceDataStartIndex cannot be less than 0.");
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      if (!data.IsCreated || data.Length == 0)
        throw new UnityException("No texture data provided to SetPixelData.");
      this.SetPixelDataImpl((IntPtr) data.GetUnsafeReadOnlyPtr<T>(), mipLevel, UnsafeUtility.SizeOf<T>(), data.Length, sourceDataStartIndex);
    }

    public unsafe NativeArray<T> GetPixelData<T>(int mipLevel) where T : struct
    {
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      if (mipLevel < 0 || mipLevel >= this.mipmapCount)
        throw new ArgumentException("The passed in miplevel " + mipLevel.ToString() + " is invalid. The valid range is 0 through  " + (this.mipmapCount - 1).ToString());
      if (this.GetImageDataPointer().ToInt64() == 0L)
        throw new UnityException("Texture '" + this.name + "' has no data.");
      ulong pixelDataOffset = this.GetPixelDataOffset(mipLevel);
      ulong length = this.GetPixelDataSize(mipLevel) / (ulong) UnsafeUtility.SizeOf<T>();
      NativeArray<T> array = length <= (ulong) int.MaxValue ? NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<T>((void*) new IntPtr((long) this.GetImageDataPointer() + (long) pixelDataOffset), (int) length, Allocator.None) : throw this.CreateNativeArrayLengthOverflowException();
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<T>(ref array, this.GetSafetyHandleForSlice(mipLevel));
      return array;
    }

    private static void ValidateIsNotCrunched(TextureCreationFlags flags)
    {
      if ((flags &= TextureCreationFlags.Crunch) != 0)
        throw new ArgumentException("Crunched Texture3D is not supported.");
    }

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetPixelImpl_Injected(int mip, int x, int y, int z, ref Color color);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetPixelImpl_Injected(int mip, int x, int y, int z, out Color ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetPixelBilinearImpl_Injected(
      int mip,
      float u,
      float v,
      float w,
      out Color ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetSafetyHandleForSlice_Injected(int mipLevel, out AtomicSafetyHandle ret);
  }
}
